Repository navigation
Conversation
…pacts retries and caps strings Adds mapAuditLevel, redactKeys, redactedValue, compactErrors and maxAttributeLength options, all on by default. Adds compactErrorSerializer and defaultOtelRedactKeys exports.
… otel createLogger throws when a removed option is passed. The level: 'audit' guard now applies only to the logger-level otel placement.
…l peer, release 3.0.0 The real-transport spec runs on 0.29 and the latest line under npm aliases. Lint forbids OpenTelemetry imports in library source. PR CI also runs for the v2.x branch.
otelAttributesFormat no longer redacts requestBodyValues, compacts retries
or caps strings by default: redactKeys, redactedValue, compactErrors,
defaultOtelRedactKeys and compactErrorSerializer are removed.
- createErrorSerializer({ omit, dedupe }) leaves properties out of every
error, or writes a shared object once. serializeError is its default.
- maxAttributeLength is off by default.
- The README shows the AI SDK setup as an example built from redactPaths,
createErrorSerializer and maxAttributeLength, and the transport spec
runs that example on 0.29 and the latest line.
cuzzlor
left a comment
There was a problem hiding this comment.
Dual review summary
Findings: 8 (blocker 0, major 1, minor 5, nit 2)
The change is coherent. One otel option replaces three, createErrorSerializer is a small extension of the existing walk, and the real-transport spec runs on both 0.29 and 0.34. The main risk is an audit-severity regression: the audit mapping now runs after loggerOptions.format but compares the mutable info.level, so a format such as format.colorize() stops audit records from being mapped. The upgrade docs also miss that otelAttributesFormat now maps audit by default. The reviewers disagreed on overall quality: Claude found no code defect, and GPT found the audit regression. On omit being called for plain error-shaped objects, they agreed on the diagnosis but disagreed on the fix.
Findings
- major: Audit mapping fails after a format that changes
info.level(gpt-only) - minor:
omitis called for plain objects that look like errors (disputed) - minor: Migration guide does not mention the new audit-mapping default (claude-only)
- minor: The claim that two
api-logscopies drop every line is wrong in most cases (claude-only) - minor: Surrogate-pair test does not exercise the surrogate guard (claude-only)
- minor: A
maxAttributeLengthbelow 11 is exceeded (gpt-only) - nit: Warning about
mapAuditLevel: falseapplies only whenlogSeverityis set (claude-only) - nit:
jsonStringifyValuesFormatJSDoc still recommends it for the OpenTelemetry transport (claude-only)
Findings not anchored to the diff
No line comment could be attached to these findings.
- nit:
jsonStringifyValuesFormatJSDoc still recommends it for the OpenTelemetry transport- Impact: The JSDoc at
src/json-stringify-values-format.ts:5-7still names "OTEL + Azure Log Analytics" as the use case, but 3.0 supports only transport 0.29 and later, where this format turns an error into oneexception.messagestring (src/otel-transport.spec.ts:193), and IDE users see this text rather than the updated README row atREADME.md:376. - Recommendation: Match the README: say the format is for sinks other than the OpenTelemetry transport, and that the transport needs
otelAttributesFormat.
- Impact: The JSDoc at
Generated by dual-review — Claude + litellm/azure/gpt-5.6-sol.
- Read the audit level from LEVEL, so a format such as colorize() before otel no longer stops audit records being mapped. Keep an existing logLevel so a second pass stays idempotent. - Cap a string to as much of [Truncated] as fits when maxAttributeLength is shorter than the marker, and cut nothing for a negative or NaN limit. - Make the surrogate-pair test cut inside a pair. - Document that omit also runs for plain objects with a string name, message and stack. - README: cover the audit-mapping default in Migrating from v2, state when two api-logs copies drop lines, and make the severityMapping warning unconditional. Point jsonStringifyValuesFormat users at otelAttributesFormat for the OpenTelemetry transport.
|
The unanchored nit from the review, the |
createLogger({ otel: true }) now gives otelAttributesFormat to each
OpenTelemetryTransportV3 on the logger that has no format of its own: the
one WinstonInstrumentation adds, and any passed in transports. The console
and other transports keep nested values and level 'audit'.
- The audit mapping runs after the transport's level filter, so the
level: 'audit' guard is removed.
- A spec runs the real WinstonInstrumentation before winston loads, as an
app's tracing module does, and checks the exported records and a sibling
transport.
- The README leads with one setup: WinstonInstrumentation beside the other
instrumentations, and otel: true. The per-transport placement and its
examples are gone, and Migrating from v2 maps every 2.x setup onto it.
Azure Monitor keeps the severity number but not severityText, so the alternative lost the audit/info distinction that logLevel keeps.
otelAttributesFormat always writes logLevel and exports audit at info severity. The rewrite only touches a record at the audit level, so a logger without one has nothing rewritten. Turning it off only lost logLevel, which App Insights needs to tell audit from info and debug from verbose, or left audit records with no severity.
…kTransport - README: a three-step quick start (instrument, create the logger, send audit records to their own table) replaces the environment-driven configuration example, the hand-written audit transport and the OpenTelemetry setup section. - CallbackTransport: onlyLevels forwards exact levels, because level is a threshold and level: 'audit' also forwards error and warn. closeTimeoutMs bounds how long close() waits for dispatches still running, and reports them through logError.
- Quick start: name @opentelemetry/instrumentation for the ESM hook, say what a CommonJS app does instead, and tighten the audit notes. - Replace the claim that Azure Monitor ignores a record with no severity: the collector files it as Information and the JS exporter sends none. - Describe otel as shaping every OpenTelemetry transport on the logger, and stop presenting otelAttributesFormat on a transport as the first choice. - Remove a repeated sentence from Log levels, and stale wording in the formats table, the ESLint comment and a test title.
Closes #156.
v3 has one OpenTelemetry setup.
WinstonInstrumentationruns beside the other instrumentations and adds the transport, andcreateLogger({ otel: true })shapes what that transport receives. Only@opentelemetry/winston-transport0.29 and later is supported. The README opens with a quick start that shows the whole setup.Merging publishes 3.0.0 as
latest. Squash-merge, because the intermediate commits do not each pass.Breaking changes
flatten,flattenReplacerandmapAuditLevelForOtelare removed fromcreateLogger. They are type errors, andcreateLoggerthrows if one is passed, so options built from config cannot fall back to nested output without a warning.otelshapes only the OpenTelemetry transport. 2.xflattenflattened every transport, the console included.otelAttributesFormatalways mapsaudittoinfoseverity and writeslogLevelon every record.@opentelemetry/winston-transportis an optional peer dependency at>=0.29. npm 7 and later refuse to install it beside an older transport.Datein OpenTelemetry output is written unquoted.What changed
createLogger({ otel })otelAttributesFormatto eachOpenTelemetryTransportV3on the logger that has no format of its own: the transportWinstonInstrumentationadds, and any passed intransports. The transport is matched by class name, because this library does not depend on it.level: 'audit'keeps audit records.otelAttributesFormataudittoinfoseverity and writeslogLevel. A logger with noauditlevel has nothing to rewrite, and App Insights needslogLevelto tellauditfrominfoanddebugfromverbose. The level is read fromLEVEL, socolorize()cannot stop the mapping. Adds an opt-inmaxAttributeLengthcap that ends in[Truncated].CallbackTransportonlyLevelsforwards exact levels:levelis a threshold, solevel: 'audit'also forwardserrorandwarn.closeTimeoutMsbounds how longclose()waits for dispatches still running, and reports them throughlogError.createErrorSerializeromit(key, error)leaves properties out of every error, anddedupewrites a shared object once.serializeErroris this factory with no options.@opentelemetry/*, so the optional peer cannot become a real dependency.auditmeans", "Record size and privacy" with an AI SDK example, and "Migrating from v2".The library has no knowledge of any consumer's libraries. The AI SDK setup is a README example built from
redactPaths,createErrorSerializerandmaxAttributeLength, and the real-transport spec runs it.Suggested review order
src/index.ts: theoteloption,shapeOtelTransports, and the check for removed options.src/otel-attributes-format.tsandsrc/audit-level.ts: the record shape and the audit mapping.src/callback-transport.tsandsrc/serialize-error.ts: the new options.src/winston-instrumentation.spec.tsandsrc/otel-transport.spec.ts: the end-to-end proof.Tests
winston-instrumentation.spec.tsruns the realWinstonInstrumentationin its own process, loaded before winston as an app's tracing module is. It checks the exported records and that a sibling transport stays nested.otel-transport.spec.tsdrives the real transport on 0.29 and the latest line into an in-memory logs SDK. It also pins one upstream behaviour: with noerrorerroron a record, the transport takes a metadata object with anameas the exception. The README documents it.Release
v2.xis cut from 2.3.0 for fixes only. Its publish workflow runs by hand and publishes under thelatest-2dist-tag, so a 2.x release never moveslatest. PR CI also runs for PRs intov2.x.otel: truereplacesflattenandmapAuditLevelForOtel, and thelogging.flattenconfig key goes. Its audit transport can useonlyLevelsandcloseTimeoutMsin place of its own level check and shutdown timeout.disableLogSending: trueandmapAuditLevelForOtel, and setotel: true.OpenTelemetryTransportV3withWinstonInstrumentation, loaded before anything imports winston as in step 1 of the quick start, and setotel: true. In the same change, move the transport to 0.29+ and the SDK to 0.219+.Verification
npm run build: lint, types, rollup, attw and the CJS smoke test pass.npm test: 240 tests pass.npm run auditpasses.npm packofdistinstalled in a scratch project: refused beside transport 0.27, installs beside 0.34.